﻿using System;
using System.Text;

namespace CommServer.Common.Json
{
    public class JsonPrimitive : JsonValue
    {
        private readonly JsonType _jsonType;
        private readonly object _value;

        #region 公开属性

        internal override object Value
        {
            get { return _value; }
        }

        public override sealed JsonType JsonType
        {
            get { return _jsonType; }
        }

        public override int Count
        {
            get { return 1; }
        }

        #endregion

        #region 构造函数

        internal JsonPrimitive(object value)
        {
            CheckNull(value, "value");
            Type type = value.GetType();
            if (type == typeof(bool))
            {
                _jsonType = JsonType.Boolean;
            }
            else
            {
                if (type == typeof(byte) ||
                    type == typeof(sbyte) ||
                    type == typeof(decimal) ||
                    type == typeof(double) ||
                    type == typeof(short) ||
                    type == typeof(ushort) ||
                    type == typeof(int) ||
                    type == typeof(uint) ||
                    type == typeof(long) ||
                    type == typeof(ulong) ||
                    type == typeof(float))
                {
                    _jsonType = JsonType.Number;
                }
                else
                {
                    if (type != typeof(string) && type != typeof(char) && type != typeof(DateTime))
                    {
                        throw new ArgumentException("Type not supported on JsonPrimitive");
                    }
                    _jsonType = JsonType.String;
                }
            }
            _value = value;
        }

        public JsonPrimitive(bool value)
        {
            _jsonType = JsonType.Boolean;
            _value = value;
        }

        public JsonPrimitive(byte value)
        {
            _jsonType = JsonType.Number;
            _value = value;
        }

        public JsonPrimitive(sbyte value)
        {
            _jsonType = JsonType.Number;
            _value = value;
        }

        public JsonPrimitive(decimal value)
        {
            _jsonType = JsonType.Number;
            _value = value;
        }

        public JsonPrimitive(short value)
        {
            _jsonType = JsonType.Number;
            _value = value;
        }

        public JsonPrimitive(ushort value)
        {
            _jsonType = JsonType.Number;
            _value = value;
        }

        public JsonPrimitive(int value)
        {
            _jsonType = JsonType.Number;
            _value = value;
        }

        public JsonPrimitive(long value)
        {
            _jsonType = JsonType.Number;
            _value = value;
        }

        public JsonPrimitive(ulong value)
        {
            _jsonType = JsonType.Number;
            _value = value;
        }

        public JsonPrimitive(float value)
        {
            _jsonType = JsonType.Number;
            _value = value;
        }

        public JsonPrimitive(double value)
        {
            _jsonType = JsonType.Number;
            _value = value;
        }

        public JsonPrimitive(string value)
        {
            CheckNull(value, "value");
            _jsonType = JsonType.String;
            _value = value;
        }

        public JsonPrimitive(char value)
        {
            _jsonType = JsonType.String;
            _value = value;
        }

        public JsonPrimitive(DateTime value)
        {
            _jsonType = JsonType.String;
            _value = value.ToString("yyyy-MM-dd HH:mm:ss");
        }

        #endregion

        #region 序列化构造

        /// <summary>
        ///     在StringBuilder中构建该对象的Json格式字符串输出
        /// </summary>
        /// <param name="builder">操作的StringBuilder对象</param>
        internal override void Builder(StringBuilder builder)
        {
            CheckNull(builder, "builder");
            if (_jsonType == JsonType.String)
            {
                #region 字符串

                builder.Append("\"");
                char[] chars = _value.ToString().ToCharArray();

                foreach (char c in chars)
                {
                    switch (c)
                    {
                        case '\0':
                            break;
                        case '"':
                            builder.Append("\\\"");
                            break;
                        case '\\':
                            builder.Append("\\\\");
                            break;
                        case '\b':
                            builder.Append("\\b");
                            break;
                        case '\f':
                            builder.Append("\\f");
                            break;
                        case '\n':
                            builder.Append("\\n");
                            break;
                        case '\r':
                            builder.Append("\\r");
                            break;
                        case '\t':
                            builder.Append("\\t");
                            break;
                        case '/':
                            builder.Append("\\/");
                            break;
                        default:
                            if (UnescapedUnicode)
                            {
                                int code = System.Convert.ToInt32(c);
                                if ((code >= 32) && (code <= 126))
                                {
                                    builder.Append(c);
                                }
                                else
                                {
                                    builder.Append("\\u" + System.Convert.ToString(code, 16).PadLeft(4, '0'));
                                }
                            }
                            else
                            {
                                builder.Append(c);
                            }
                            break;
                    }
                }
                builder.Append("\"");

                #endregion 字符串
            }
            else if (_jsonType == JsonType.Boolean)
            {
                //逻辑型
                builder.Append(_value.ToString().ToLower());
            }
            else
            {
                builder.Append(_value);
            }
        }

        #endregion

        /// <summary>
        ///     输出标准Json字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return _value.ToString();
        }
    }
}
